#include <string.h>

typedef int i32;
typedef unsigned long long u64;

struct Point {
  u64 x;
  u64 y;
  u64 z;
  u64 color;
};

struct Point pt1 = { 1, 2, 3, 0 };
struct Point pt2 = { 4, 5, 6, 1 };
struct Point pt3 = { 7, 8, 9, 0 };

// ivopts
long long int a = 40086400407707;
long long int h[];
__attribute__((always_inline)) inline
void fn1(unsigned int p1, unsigned char p2, long long int p3) {
  for (unsigned int k = 0; k < (unsigned int)p3 - 3785955758; k++)
    for (int l = 0; l < p2 + 0; l += (int)p1 + 212968535) {
      a = 2052578427 / p1 ? p2 << 0 : 0;
      h[0 * 2 + 0 * 1 + 9 + l] = 0;
    }
}

// simplify memop
int memset_s(void *dest, size_t destMax, int c, size_t count);
int memcpy_s(void *dest, size_t destMax, const void *src, size_t count);
__attribute__((always_inline)) inline
void test_simplify_memop() {
  memset_s(&pt1, sizeof(struct Point), 0, sizeof(struct Point));
  memcpy_s(&pt3, sizeof(struct Point), &pt2, sizeof(struct Point));
}

// outline
// [CHECK_OS] CHECK-DAG: outlined_func
void bar(int x); 
int oltest(int a, int b) {
  int x = a * b + b;
  bar(x);
  bar(x + a);
  bar(x * a);
  bar(x / a);
  int y = a * b + b;
  bar(y);
  bar(y + a);
  bar(y * a);
  bar(y / a);
  return x + y;
}

// put them all
__attribute__((noinline)) void foo(i32 *__restrict__ dst, u64 x) {
  // slp
  // When tree node type (u64 here) is different from tree type (i32 here),
  // SLP should add extra cvt if needed.
  // [CHECK_O2] CHECK-DAG: dup
  dst[0] &= x;
  dst[1] &= x;
  dst[2] &= x;
  dst[3] &= x;
  fn1(4081998765, 4, 5355693358539413953);
  test_simplify_memop();
  oltest(100, 200);
}

int main() {
  i32 arr[] = {1, 2, 3, 4};
  foo(arr, 42);
  return 0;
}

